package com.schoolai.auth.service;

import com.alibaba.fastjson.JSON;
import com.nimbusds.jose.JOSEException;
import com.schoolai.util.base.Result;
import com.schoolai.util.tools.JWTUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.interfaces.RSAPrivateKey;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Copyright(C),2019-2025，XX公司
 * FileName:MyAuthenticationSuccessHandler
 * Author:bobby
 * 创建时间：2025/10/21 09:40
 * Description:成功响应
 * History:
 * <auth>        <time>       <version>       <desc>
 * 作者          修改时间       版本号         描述
 */
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Value("${rsa.privateKey.jks-file}")
    private String jksFile;
    /**
     * @description:私钥参数
     */
    @Value("${rsa.privateKey.alias}")
    private String alias;
    @Value("${rsa.privateKey.password}")
    private String password;
    /**
     * @description:令牌参数
     */
    @Value("${JWT.subject}")
    private String subject;
    @Value("${JWT.issuer}")
    private String issuer;
    @Value("${JWT.TTL}")
    private Long TTL;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String token = authToken(authentication);
        //返回响应
        HashMap<String,Object> reponseMap = new HashMap<String,Object>();
        reponseMap.put("token", token);
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 定义格式化模式：年月日时分秒
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 格式化时间
        String formattedDateTime = now.format(formatter);
        reponseMap.put("createdTime", formattedDateTime);
        reponseMap.put("TTL",TTL);
        // 如果redis中有数据就删除原来的数据，新增一条记录,用于网关判断认证token
        if(stringRedisTemplate.opsForValue().get(authentication.getName()) == null){
            stringRedisTemplate.opsForValue().set(authentication.getName(),token,Duration.ofMillis(TTL));
        }else {
            stringRedisTemplate.delete(authentication.getName());
            stringRedisTemplate.opsForValue().set(authentication.getName(),token,Duration.ofMillis(TTL));
        }
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(JSON.toJSONString(Result.ok(reponseMap)));
    }


    private String authToken(Authentication authentication) throws IOException {
        ClassPathResource classpathResource = new ClassPathResource(jksFile);
        // 2. 从JKS文件加载私钥
        FileInputStream fis = new FileInputStream(classpathResource.getFile());
        RSAPrivateKey privateKey = null;
        JWTUtil jwtUtil = new JWTUtil();
        try {
            privateKey = jwtUtil.loadPrivateKeyFromJKS(fis, alias, password);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String token = null;
        //获取用户身份信息
        //创建结果对象
        Object principal = authentication.getPrincipal();
        // 项目中有自定义字段，所有就用JwtUser类，因为该类是实现UserDetails接口
        if (principal instanceof JwtUser) {
            JwtUser userDetails = (JwtUser) principal;
            HashMap<String, Object> userDetailsMap = new HashMap<>();
            userDetailsMap.put("username", userDetails.getUsername());
            userDetailsMap.put("authorities", userDetails.getAuthorities());
            userDetailsMap.put("uid",userDetails.getUid());
            userDetailsMap.put("email",userDetails.getEmail());
            userDetailsMap.put("uid",userDetails.getUid());
            userDetailsMap.put("email",userDetails.getEmail());
            userDetailsMap.put("nickName",userDetails.getNickName());
            userDetailsMap.put("imageUrl",userDetails.getImageUrl());
            userDetailsMap.put("mobile",userDetails.getMobile());
            userDetailsMap.put("isAccountNonExpired",userDetails.isAccountNonExpired());
            userDetailsMap.put("isAccountNonLocked",userDetails.isAccountNonLocked());
            userDetailsMap.put("isCredentialsNonExpired",userDetails.isCredentialsNonExpired());
            userDetailsMap.put("isEnabled",userDetails.isEnabled());
            List authoritieCodes = new ArrayList<>();
            userDetails.getAuthorities().forEach(authority->authoritieCodes.add(authority.getAuthority()));
            // 直接传userDetails.getAuthorities()生成的token报错，所以这里给他转化
            userDetailsMap.put("authorities",authoritieCodes);

            try {
                token = "Bearer "+jwtUtil.generateToken(
                        privateKey,
                        subject,
                        issuer,
                        TTL, // 1小时
                        userDetailsMap
                );
            } catch (Exception e) {
                log.error("生成token失败"+e.getMessage());
            }

        }
        return token;
    }
}
